//**
//*******************************************************************************
//* @file main.c
//* @author ABOV R&D Division
//* @brief Main program
//*
//* Copyright 2022 ABOV Semiconductor Co.,Ltd. All rights reserved.
//*
//* This file is licensed under terms that are found in the LICENSE file
//* located at Document directory.
//* If this file is delivered or shared without applicable license terms,
//* the terms of the BSD-3-Clause license shall be applied.
//* Reference: https://opensource.org/licenses/BSD-3-Clause
//*******************************************************************************
//======================================================
// Main program routine
// - Device name  : A94B114
// - Package type : 20SOP
// Generated    : Wed, Jul 02, 2025 (13:13:32)
//======================================================
// MAIN is used for XDATA variable : V1.041.00 ~
#define MAIN 1 // Do not delete this line

#include "A94B114.h"
#include "delay.h"
#include "typedef.h"
#include "rgb.h"
#include "spi.h"
/* 声明 */
void port_init(void);
void clock_init(void);
void LVI_init(void);
void ExINT_init(void);
void Timer2_init(void);
/* on off flag */
bool led_flag;
/* led running package */
struct _rgb_package init_rgb;
struct _my_color set_color_index;
uint8_t write_data[4] = {0xF0, 0x0F, 0x03, 0x04};
void main(void)
{
	cli(); // disable INT. during peripheral setting
	WDTMR = 0;
	port_init();   // initialize ports
	clock_init();  // initialize operation clock
	ExINT_init();  // initialize external __interrupt
	Timer2_init(); // initialize Timer2
	LVI_init();	   // initialize LVI, LVR

	sei(); // enable INT.
	init_rgb.led_index = 0;
	init_rgb.led_on_off = init_rgb.color_index = 24;
	// TODO: add your main code here

	while (1)
	{
		for (uint8_t i = 0; i < 4; i++)
			SpiSend(write_data[i]);

		if ((set_color_index.color.red == 150) || (set_color_index.color.red == 0))
		{

			led_flag = !led_flag;
		}
		if (led_flag)
		{
			set_color_index.color.red++;
			set_color_index.color.green++;
			set_color_index.color.blue++;
		}
		else
		{
			set_color_index.color.red--;
			set_color_index.color.green--;
			set_color_index.color.blue--;
		}
		init_rgb.rgb[0] = set_color_index.data;
		init_rgb.rgb[1] = set_color_index.data;
		init_rgb.rgb[2] = set_color_index.data;
		init_rgb.led_index = 0;
		init_rgb.color_index = 23;
		if (init_rgb.rgb[init_rgb.led_index] & set_bit[init_rgb.color_index])
		{
			T2BDR = CODE_1; // duty Low
		}
		else
		{
			T2BDR = CODE_0; // duty high
		}
		T2CRH |= 0x80; // enable timer
		delay_ms(20);
	}
}

//======================================================
// __interrupt routines
//======================================================

void INT_Ext0_1_2(void) __interrupt(4)
{
	// External __interrupt 0,1,2
	// TODO: add your code here

	//========================================================
	if (EIFLAG & 0x04)
		EIFLAG = (uint8_t)~0x04; // clear Ext. INT2
	if (EIFLAG & 0x02)
		EIFLAG = (uint8_t)~0x02; // clear Ext. INT1
	if (EIFLAG & 0x01)
		EIFLAG = (uint8_t)~0x01; // clear Ext. INT0
}

void INT_Timer2(void) __interrupt(11)
{
	// Timer2 match __interrupt

	// TODO: add your code here
	init_rgb.led_on_off = init_rgb.color_index;
	if (0 == init_rgb.led_on_off)
	{
		init_rgb.led_index++;
		init_rgb.color_index = 24;
	}
	if (init_rgb.led_index == LED_NUM)
		return;
	init_rgb.color_index -= 1;
	if (init_rgb.rgb[init_rgb.led_index] & set_bit[init_rgb.color_index])
	{
		T2BDR = CODE_1; // duty Low
	}
	else
	{
		T2BDR = CODE_0; // duty high
	}
	T2CRH |= 0x80; // enable timer
}

//======================================================
// Peripheral setting routines
//======================================================

void ExINT_init(void)
{
	// initialize external __interrupt
	EIPOL0 = 0x00; // polarity 10 ~ 12
	EIPOL1 = 0x08; // polarity 0 ~ 2
	EIFLAG = 0x00; // clear Ext. INT 0,1,2 flags
	IE |= 0x10;	   // enable Ext. INT. 0, 1, 2
}

void LVI_init(void)
{
	// initialize LVI, LVR
	LVIR = 0x00;  // set LVI & LVR
	DBTSR = 0x00; // set debounce
}

void Timer2_init(void)
{
	// initialize Timer2
	// 16bit PWM, period = 0.001000mS ( 1000000.000000Hz )
	//     PWM duty = 25.000000%
	T2CRH = 0x22;  // PWM setting High, 1 shot mode
	T2CRL = 0xA1;  // PWM setting Low
	T2BDRH = 0x00; // duty High
	T2BDRL = 0x03; // duty Low
	T2ADRH = 0x00; // period count High
	T2ADRL = 0x0F; // period count Low

	IE1 |= 0x40;   // Enable Timer interrupt
	T2CRH |= 0x80; // enable timer
}

void clock_init(void)
{
	SYSCON_AR = 0x5A; // Enable permission to access SCCR

	// internal RC clock (16.0MHz)
	OSCCR = 0x04;	  // Set High freq. OSC
	SYSCON_AR = 0x00; // Disable permission
}

void port_init(void)
{
	// initialize ports
	//   2 : PWM2o    out 0
	//   6 : P14      out 1
	//   7 : P15      out 0
	//   8 : P20      out 1
	//  16 : EINT1    in  0
	P0IO = 0xFF; // direction
	P0PU = 0x02; // pullup
	P0OD = 0x00; // open drain
	P0DB = 0x00; // debounce
	P0 = 0x00;	 // port initial value

	P1IO = 0xFF; // direction
	P1PU = 0x31; // pullup
	P1OD = 0x00; // open drain
	P1DB = 0x00; // debounce
	P1 = 0x00;	 // port initial value

	P2IO = 0xFB; // direction
	P2PU = 0x05; // pullup
	P2OD = 0x00; // open drain
	P2DB = 0x00; // debounce
	P2 = 0x00;	 // port initial value

	// Set port functions
	P0FSRL = 0x00; // P03~00
	P0FSRH = 0x00; // P07~04
	P1FSRL = 0x02; // P13~10
	P1FSRH = 0x00; // P17~14
	P2FSR = 0x10;  // P23~20
}
